//
//  UIImage+CLAdjust.swift
//  CLExtension
//
//  Created by CharlieLiao on 2017/8/22.
//  Copyright © 2017年 Charlie. All rights reserved.
//

import Foundation

extension UIImage
{
    /// 剪切image
    @objc public func clips(rect: CGRect) -> UIImage?
    {
        let image: UIImage?
        UIGraphicsBeginImageContext(rect.size)
        if let ctx = UIGraphicsGetCurrentContext() {
            ctx.ctm.translatedBy(x: 0, y: size.height)
            ctx.ctm.scaledBy(x: 1, y: -1)
            ctx.draw(cgImage!, in: CGRect(x: rect.origin.x, y: rect.origin.y, width: size.width, height: size.height))
            ctx.clip(to: rect)
            image = UIGraphicsGetImageFromCurrentImageContext()
        } else {
            image = nil
        }
        UIGraphicsEndImageContext()
        return image
    }
    
    /// image旋转
    @objc public func rotate(_ rotate: CGFloat) -> UIImage?
    {
        let image: UIImage?
        UIGraphicsBeginImageContext(size)
        if let ctx = UIGraphicsGetCurrentContext() {
            //做CTM变换
            ctx.ctm.rotated(by: rotate)
            //绘制图片
            ctx.draw(cgImage!, in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
            image = UIGraphicsGetImageFromCurrentImageContext()
        } else {
            image = nil
        }
        UIGraphicsEndImageContext()
        return image
    }
    
    /// x翻转
    @objc public func flipX() -> UIImage?
    {
        let image: UIImage?
        UIGraphicsBeginImageContext(size)
        if let ctx = UIGraphicsGetCurrentContext() {
            ctx.ctm.translatedBy(x: 0, y: size.height)
            ctx.ctm.scaledBy(x: 1, y: -1)
            ctx.ctm.translatedBy(x: size.width, y: 0)
            ctx.ctm.scaledBy(x: -1, y: 1)
            //绘制图片
            ctx.draw(cgImage!, in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
            image = UIGraphicsGetImageFromCurrentImageContext()
        } else {
            image = nil
        }
        UIGraphicsEndImageContext()
        return image
    }
    
    /// 获取圆角图片
    @objc public func roundRect(size: CGSize, radius: CGFloat) -> UIImage
    {
        return roundRect(size: size, radius: radius, borderWidth: 0, borderColor: UIColor.clear)
    }
    
    /// 获取圆角图片(带边框)
    @objc public func roundRect(size: CGSize, radius: CGFloat, borderWidth:CGFloat, borderColor:UIColor) -> UIImage
    {
        // 初始值
        let scale = self.size.width / size.width;
        let bWidth = borderWidth * scale
        let radius = radius * scale
        
        let react = CGRect(x: bWidth, y: bWidth, width: self.size.width - 2*bWidth, height: self.size.height - 2*bWidth)
        
        //绘制图片设置
        UIGraphicsBeginImageContextWithOptions(self.size, false, UIScreen.main.scale)
        
        let path = UIBezierPath(roundedRect:react, cornerRadius:radius)
        //绘制边框
        path.lineWidth = bWidth
        borderColor.setStroke()
        path.stroke()
        path.addClip()
        //画图片
        draw(in: react)
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        
        return newImage!;
    }
    
    
    public func compressImage(toByte maxLength: Int) -> (image: UIImage, data: Data) {
        
        var data = compressImageQuality(toByte: maxLength)
        var resultImage = UIImage(data: data, scale: 1)!
        
        if  data.count < maxLength { return (resultImage, data) }
        
        // Compress by size
        var lastDataLength: Int = 0
        while data.count > maxLength, data.count != lastDataLength {
            lastDataLength = data.count
            let ratio: CGFloat = CGFloat(maxLength) / CGFloat(data.count)
            let size: CGSize = CGSize(width: Int(resultImage.size.width * sqrt(ratio)),
                                      height: Int(resultImage.size.height * sqrt(ratio)))
            UIGraphicsBeginImageContext(size)
            resultImage.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
            resultImage = UIGraphicsGetImageFromCurrentImageContext()!
            UIGraphicsEndImageContext()
            
            data = resultImage.compressImageQuality(toByte: maxLength)
            resultImage = UIImage(data: data, scale: 1)!
        }
        return (resultImage, data)
    }
    
    
    func compressImageQuality(toByte maxLength: Int) -> Data {
        var compression: CGFloat = 1
        
        var data = jpegData(compressionQuality: compression)!
        if data.count > maxLength {
            // Compress by size
            var max: CGFloat = 1
            var min: CGFloat = 0
            for _ in 0..<6 {
                compression = (max + min) / 2
                data = jpegData(compressionQuality: compression)!
                if CGFloat(data.count) < CGFloat(maxLength) * 0.9 {
                    min = compression
                } else if data.count > maxLength {
                    max = compression
                } else {
                    break
                }
            }
        }
        
        return data
    }
    
    /// image 比例缩放
    public func scaleBy(factor: CGFloat) -> UIImage? {
        
        let newSize = CGSize(width: size.width*factor, height: size.height*factor)
        UIGraphicsBeginImageContext(newSize)
        let transform = CGAffineTransform.identity.scaledBy(x: factor, y: factor)
        UIGraphicsGetCurrentContext()?.concatenate(transform)
        draw(in: CGRect(origin: .zero, size: newSize))
        let newImg = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return newImg
    }
    
    /// image长宽等比缩放 newSize
    public func scaleBy(size newSize: CGSize) -> UIImage? {
        let maxSide = max(size.width, size.height)
        let newMaxSide = max(newSize.width, newSize.height)
        if maxSide > newMaxSide {
            return scaleBy(factor: newMaxSide/maxSide)
        }
        return self
    }
    
    ///  image缩放 newSize
    public func resizeTo(size newSize: CGSize) -> UIImage? {
        UIGraphicsBeginImageContext(newSize)
        guard let content = UIGraphicsGetCurrentContext() else {
            UIGraphicsEndImageContext()
            return nil
        }
        content.translateBy(x: 0, y: newSize.height)
        content.scaleBy(x: 1, y: -1)
        content.draw(self.cgImage!, in: CGRect(origin: .zero, size: newSize))
        let newImg = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return newImg
    }
}

